#include "Date.h"
#include <assert.h>
#include <time.h>



Date Date::getCurrentDate()
{
	time_t now;
	struct tm *tm_now;
	time(&now);
	tm_now = localtime(&now);
	return  Date(tm_now->tm_year + 1900, tm_now->tm_mon + 1, tm_now->tm_mday);
}


Date Date::FormatDate(int nValue)
{
	return Date(nValue / 10000, nValue % 10000 / 100, nValue % 100);
}


bool Date::InvailedDate(Date date)
{
	if (date.Year() >= 1900 && date.Year() < 10000
		&& date.Month() > 0 && date.Month() < 13
		&& date.Day() > 0
		&& date.Day() <= date.GetDaysInMonth(date.Year(), date.Month()))
		return true;

	return false;
}


int Date::CaculateWeekDay()
{
	int m(_month), y(_year), d(_day);
	if (m == 1 || m == 2) {
		m += 12;
		y--;
	}
	int iWeek = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;
	return iWeek + 1;
}

Date::Date(int year, int month, int day)
{
	if (year >= 1900 && (month > 0 && month < 13) &&
		(day > 0 && day <= GetDaysInMonth(year, month)))
	{
		_year = year;
		_month = month;
		_day = day;
	}
	else {
		assert(0);
	}
}

Date::Date(const Date& date) : _year(date._year), _month(date._month), _day(date._day) {}

Date& Date::operator=(const Date& date)
{
	if (this != &date) {
		_year = date._year;
		_month = date._month;
		_day = date._day;
	}
	return *this;
}

Date Date::operator+(int day)
{
	Date temp(*this);
	if (day < 0) {
		day = -day;
		return temp - day;
	}
	temp._day += day;
	while (temp._day > GetDaysInMonth(temp._year, temp._month)) {
		temp._day -= GetDaysInMonth(temp._year, temp._month);
		if (temp._month == 12) {
			temp._year++;
			temp._month = 1;
		}
		else {
			temp._month++;
		}
	}
	return temp;
}

Date& Date::operator++()
{
	return (*this = *this + 1);
}

Date Date::operator++(int)
{
	Date temp(*this);
	*this = *this + 1;
	return temp;
}

Date Date::operator-(int day)
{
	Date temp(*this);
	temp._day -= day;
	while (temp._day <= 0) {
		if (temp._month == 1) {
			temp._year--;
			temp._month = 12;
		}
		else {
			temp._month--;
		}
		temp._day += GetDaysInMonth(temp._year, temp._month);
	}
	return temp;
}

int Date::operator-(const Date& date)
{
	Date maxDate(*this);
	Date minDate(date);
	if (maxDate < minDate) {
		maxDate = date;
		minDate = *this;
	}
	int days = 0;
	while (1) {
		if (minDate + days == maxDate)
			break;
		days++;
	}
	return days;
}

Date& Date::operator--()
{
	return (*this = *this - 1);
}

Date Date::operator--(int)
{
	Date temp(*this);
	*this = *this - 1;
	return temp;
}

bool  Date::operator>(const Date& date)
{
	if (_year > date._year || (_year == date._year && _month > date._month) || (_year == date._year && _month == date._month && _day > date._day))
	{
		return true;
	}
	else
		return false;
}

bool  Date::operator<(const Date& date)
{
	if (_year < date._year || (_year == date._year && _month < date._month) || (_year == date._year && _month == date._month && _day < date._day))
	{
		return true;
	}
	else
		return false;
}

bool  Date::operator==(const Date& date)
{
	return _year == date._year && _month == date._month && _day == date._day;
}

bool  Date::operator!=(const Date& date)
{
	return _year != date._year || _month != date._month || _day != date._day;
}

bool  Date::operator>=(const Date& date)
{
	if (*this < date)
		return false;
	else
		return true;
}

bool  Date::operator<=(const Date& date)
{
	if (*this > date)
		return false;
	else
		return true;
}

